package com.aspire.boc.mms.gwcmp.action;

import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.support.RequestContext;

import com.aspire.boc.mms.gwcmp.dao.GwcmpEcMapper;
import com.aspire.boc.mms.gwcmp.dao.GwcmpLinkMapper;
import com.aspire.boc.mms.gwcmp.model.GwcmpEc;
import com.aspire.boc.mms.gwcmp.model.GwcmpLink;
import com.aspire.boc.mms.gwcmp.util.CapChecker;
import com.aspire.boc.mms.gwcmp.util.CheckResult;
import com.aspire.boc.mms.gwcmp.util.GwcmpAdminUtil;
import com.aspire.boc.mms.gwcmp.util.RandomCipher;
import com.aspire.boc.mms.gwcmp.util.enums.CapParamName;
import com.aspire.boc.mms.gwcmp.util.enums.LinkType;
import com.aspire.boc.mms.wmf.util.Page;

/**
 * 接入管理
 * 
 * @author yuanpengpeng
 * 
 */
@Controller
public class LinkAct {

	private static Log logger = LogFactory.getLog(LinkAct.class);

	private static final String linkReverseRegex = "destPattern=.+,contentPattern=.+";
	/**
	 * 接入上行路由参数正则匹配
	 */
	private Pattern linkReversePattern = Pattern.compile(linkReverseRegex);
	
	@Autowired
	private GwcmpLinkMapper gwcmplinkmapper;
	
	@Autowired
	private GwcmpEcMapper gwcmpEcMapper;

	/**
	 * 接入查询
	 * 
	 * @param start
	 *            结果集中游标开始位置
	 * @param limit
	 *            每页条数
	 * @param ecId
	 *            企业Id
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/link/getLinkList")
	@ResponseBody
	public Map<String, Object> getLinkList(
			@RequestParam(value = "start", required = true) Integer start,
			@RequestParam(value = "limit", required = true) Integer limit,
			@RequestParam(value = "ecId", required = false) String ecId,
			HttpServletRequest request, HttpServletResponse response) {
		RequestContext requestContext = new RequestContext(request);

		String operator = GwcmpAdminUtil.getLoginUserName(request);
		Map<String, Object> resultMap = new HashMap<String, Object>();

		logger.info("operator: " + operator
				+ ",operation: query link /link/getLinkList"
				+ ", params[ ecId:" + ecId + ",startSize:" + start
				+ ",limitSize:" + limit + "]");
		Map<String, Object> param = new HashMap<String, Object>();
		if (start != null && limit != null) {
			Page page = new Page(start, limit);
			param.put("page", page);
			param.put("orderByClause", "link.LATEST_OPERATE_TIME DESC");

		}
		List<GwcmpLink> list = null;
		int total = 0;
		if (StringUtils.isNotBlank(ecId)) {
			param.put("ecId", ecId);
		}
		try {
			list = gwcmplinkmapper.selectList(param);
			total = gwcmplinkmapper.selectTotal(param);
			logger.info("operator: " + operator
					+ ", operation: getLinkList, result: total=" + total
					+ ", list的长度" + list.size());
		} catch (Exception e) {
			logger.error("operator: " + operator
					+ ", operation: getLinkList, errorMsg: ", e);
			resultMap.put("msg",
					requestContext.getMessage("link.error.Exception"));
			return resultMap;
		}
		resultMap.put("total", total);
		resultMap.put("list", list);
		return resultMap;
	}


	/**
	 * 接入增加/修改
	 * 
	 * @param id
	 *            接入Id
	 * @param ecId
	 *            企业Id
	 * @param linkType
	 *            接入类型
	 * @param protocalType
	 *            协议类型
	 * @param capFlowName
	 *            流控能力接口的名称
	 * @param capAClass
	 *            cap处理模块的类名
	 * @param ipInfo
	 *            IP信息
	 * @param flowControl
	 *            流量控制
	 * @param capPriority
	 *            cap接入优先级
	 * @param capBusiness
	 *            接入业务参数
	 * @param capReverseName
	 *            cap上行路由能力接口的名称
	 * @param capReverse
	 *            上行路由参数
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/link/saveLink")
	@ResponseBody
	public Map<String, Object> saveLink(
			@RequestParam(value = "id", required = false) String id,
			@RequestParam(value = "ecId", required = true) String ecId,
			@RequestParam(value = "linkType", required = true) Short linkType,
			@RequestParam(value = "protocalType", required = true) String protocalType,
			@RequestParam(value = "capFlowName", required = false) String capFlowName,
			@RequestParam(value = "capAClass", required = false) String capAClass,
			@RequestParam(value = "ipInfo", required = false) String ipInfo,
			@RequestParam(value = "flowControl", required = false) Long flowControl,
			@RequestParam(value = "capBusiness", required = false) String capBusiness,
			@RequestParam(value = "capReverseName", required = false) String capReverseName,
			@RequestParam(value = "capReverse", required = false) String capReverse,
			HttpServletRequest request, HttpServletResponse response) {
		
		RequestContext requestContext = new RequestContext(request);
		String operator = GwcmpAdminUtil.getLoginUserName(request);
		logger.info("operator: " + operator
				+ ",operation: /link/saveLink " + ",params[ id:" + id
				+ ",ecId:" + ecId + ",linkType:" + linkType + ",protocalType:"
				+ protocalType + ",capReverse:" + capReverse + ",capAClass:"
				+ capAClass + ",capFlowName:" + capFlowName + ",ipInfo:"
				+ ipInfo + ",flowControl:" + flowControl + ",capBusiness:" + ",capFlowName:" 
				+ capFlowName+ "]");
		CheckResult result=CapChecker.checkParams(requestContext, capAClass, CapParamName.CAP_BUSINESS, capBusiness);
		Map<String, Object> resultmap = new HashMap<String, Object>();
		if(result != null && !result.isOk()) {
			resultmap.put("failure", Boolean.TRUE);
			resultmap.put("msg", result.getErrorMsgString("<br/>"));
			return resultmap;
		}
		// 上行路由参数格式错误
		if(StringUtils.isNotBlank(capReverse) && !linkReversePattern.matcher(capReverse).matches()) {
			resultmap.put("failure", Boolean.TRUE);
			resultmap.put("msg", requestContext.getMessage("common.error.cap.paramCheckFailure", new String[]{"capReverse", capReverse, linkReverseRegex}));
			return resultmap;
		}
		GwcmpEc gwcmpEc = gwcmpEcMapper.selectByPrimaryKey(ecId);
		if(gwcmpEc == null) {
			resultmap.put("failure", Boolean.TRUE);
			resultmap.put("msg", requestContext.getMessage("link.error.ecNotExists", new String[]{ecId}));
			return resultmap;
		}
		LinkType checkLinkType = LinkType.getByKey(linkType);
		if(checkLinkType == null) {
			resultmap.put("failure", Boolean.TRUE);
			resultmap.put("msg", requestContext.getMessage("common.error.paramError"));
			logger.error("operator: " + operator +",operation: /link/saveLink, param[linkType=" + linkType + "] error");
			return resultmap;
		}
		GwcmpLink gwcmplink = createLink(id, ecId, linkType, protocalType, capFlowName, capAClass, ipInfo, flowControl,
				capBusiness, capReverseName, capReverse, operator);
		try {
			if (StringUtils.isBlank(id)) {
				gwcmplink.setId(gwcmplinkmapper.getLinkIdSequence() + "");
				String password = RandomCipher.result();
				gwcmplink.setPassword(password);
				gwcmplinkmapper.insertSelective(gwcmplink);
			} else {
				gwcmplinkmapper.updateByPrimaryKeySelective(gwcmplink);
			}
		} catch (Exception e) {
			logger.error("operator: " + operator + ", operation: saveLink, errorMsg: ", e);
			resultmap.put("msg", requestContext.getMessage("common.error.systemError"));
			resultmap.put("failure", Boolean.TRUE);
			return resultmap;
		}
		resultmap.put("success", Boolean.TRUE);
		logger.info("operator: " + operator + ", operation: /link/saveLink, success");
		return resultmap;
	}

	private GwcmpLink createLink(String id, String ecId, Short linkType, String protocalType, String capFlowName,
			String capAClass, String ipInfo, Long flowControl, String capBusiness, String capReverseName,
			String capReverse, String operator) {
		GwcmpLink gwcmplink = new GwcmpLink();
		if (StringUtils.isNotBlank(id)) {
			gwcmplink.setId(id);
		}
		gwcmplink.setEcId(ecId);
		gwcmplink.setLinkType(linkType);
		gwcmplink.setLatestOperator(operator);
		gwcmplink.setCapReverseName(capReverseName);
		gwcmplink.setIpInfo(ipInfo);
		gwcmplink.setCapBusiness(capBusiness);
		if(flowControl == null) {
			flowControl = -1l;
		}
		gwcmplink.setFlowControl(flowControl);
		gwcmplink.setProtocalType(protocalType);
		gwcmplink.setLatestOperateTime(new Date());
		gwcmplink.setCapFlowName(capFlowName);
		gwcmplink.setCapAClass(capAClass);
		gwcmplink.setStatus((short) 1);
		gwcmplink.setCapReverse(capReverse);
		return gwcmplink;
	}

	/**
	 * 获取详情
	 * 
	 * @param ecId
	 *            企业Id
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/link/getLinkDetail")
	@ResponseBody
	public Map<String, Object> getLinkDetail(
			@RequestParam(value = "id", required = false) String id,
			HttpServletRequest request, HttpServletResponse response) {
		String operator = GwcmpAdminUtil.getLoginUserName(request);
		RequestContext requestContext = new RequestContext(request);
		logger.info("operator: " + operator
				+ ",operation: query link /link/getLinkDetail "
				+ ", params[ id:" + id + "]");
		Map<String, Object> result = new HashMap<String, Object>();
		GwcmpLink gwcmpLink = null;
		try {

			gwcmpLink = gwcmplinkmapper.selectByPrimaryKey(id);
			logger.info("operator: " + operator
					+ ", operation: getLinkDetail, result: gwcmpLink="
					+ gwcmpLink);
		} catch (Exception e) {
			logger.error("operator: " + operator
					+ ", operation: getLinkDetail, errorMsg: ", e);
			result.put("msg", requestContext.getMessage("link.error.Exception"));
		}
		result.put("gwcmpLink", gwcmpLink);

		result.put("single", gwcmpLink != null ? gwcmpLink : new GwcmpLink());
		return result;
	}

	/**
	 * 接入导出
	 * 
	 * @param ecId
	 *            企业Id
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "/link/exportLinkList")
	@ResponseBody
	public void exportLinkList(
			@RequestParam(value = "ecId", required = false) String ecId,
			HttpServletRequest request, HttpServletResponse response) {
		// 返回结果
		String operator = GwcmpAdminUtil.getLoginUserName(request);
		StringBuffer logInfo = new StringBuffer();
		logInfo.append("report >>>>>").append(" operator:").append(operator)
				.append(" url: /link/exportLinkList.do").append(" params: [")
				.append(",ecId=").append(ecId).append("] ");
		logger.info(logInfo.toString());
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("orderByClause", "link.LATEST_OPERATE_TIME DESC");
		if (StringUtils.isNotBlank(ecId)) {
			param.put("ecId", ecId);
		}
		List<GwcmpLink> list = gwcmplinkmapper.selectList(param);
		if (list == null)
			new ArrayList<GwcmpLink>(0);
		HSSFWorkbook workbook = exportLink(list, response);
		String filename = "JRGL_"
				+ new SimpleDateFormat("yyyyMMdd").format(new Date()) + ".xls";
		downloadExcel(workbook, filename, response);
	}

	// 创建工作量excel文件
	private HSSFWorkbook exportLink(List<GwcmpLink> list,
			HttpServletResponse response) {
		/**
		 * List<Map<String, Object>>
		 */
		HSSFWorkbook wb = new HSSFWorkbook();
		HSSFCellStyle numStyle = wb.createCellStyle();
		numStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("0"));
		int size = list == null ? 0 : list.size();
		if (size > 0) {
			int sheetSize = 5000;
			int sheetCount = (int) Math.ceil(size / sheetSize + 1);

			for (int n = 0; n < sheetCount; n++) {
				HSSFSheet sheet = wb.createSheet("表" + (n + 1));
				sheet.setDefaultColumnWidth((short) 10);
				HSSFRow rowHead = sheet.createRow(0);

				rowHead.createCell((short) 0).setCellValue(
						new HSSFRichTextString("企业ID"));
				rowHead.createCell((short) 1).setCellValue(
						new HSSFRichTextString("企业名称"));
				rowHead.createCell((short) 2).setCellValue(
						new HSSFRichTextString("IP类型"));
				rowHead.createCell((short) 3).setCellValue(
						new HSSFRichTextString("IP信息"));
				rowHead.createCell((short) 4).setCellValue(
						new HSSFRichTextString("网关用户名"));
				rowHead.createCell((short) 5).setCellValue(
						new HSSFRichTextString("网关密码"));
				rowHead.createCell((short) 6).setCellValue(
						new HSSFRichTextString("流量控制"));

				// 10001: 0-4999, 5000-9999, 10000-10001
				for (int i = n * sheetSize; i < list.size()
						&& i < (n + 1) * sheetSize; i++) {
					HSSFRow rowBody = sheet.createRow(i % sheetSize + 1);
					GwcmpLink gwcmpLink = list.get(i);
					Long flow = gwcmpLink.getFlowControl();
					short link = gwcmpLink.getLinkType();
					// String FlowControl = String.valueOf(flow);
					// if (FlowControl==String.valueOf("-1")) {
					// FlowControl="不限制";
					// }
					String FlowControl = null;
					String linkType = null;
					if (flow == -1) {
						FlowControl = "不限制";
					} else {
						FlowControl = String.valueOf(flow);
					}
					if (link == 1) {
						linkType = "彩信";
					} else {
						linkType = "短信";
					}
					rowBody.createCell((short) 0).setCellValue(
							new HSSFRichTextString(getNullString(gwcmpLink
									.getEcId())));
					rowBody.createCell((short) 1).setCellValue(
							new HSSFRichTextString(getNullString(gwcmpLink
									.getEcName())));
					rowBody.createCell((short) 2).setCellValue(
							new HSSFRichTextString(getNullString(linkType)));
					rowBody.createCell((short) 3).setCellValue(
							new HSSFRichTextString(getNullString(gwcmpLink
									.getIpInfo())));
					rowBody.createCell((short) 4).setCellValue(
							new HSSFRichTextString(getNullString(gwcmpLink
									.getId())));
					rowBody.createCell((short) 5).setCellValue(
							new HSSFRichTextString(getNullString(gwcmpLink
									.getPassword())));
					rowBody.createCell((short) 6).setCellValue(
							new HSSFRichTextString(getNullString(FlowControl)));
				}
			}
		}
		return wb;
	}

	/**
	 * @param workbook
	 * @param filename
	 * @param response
	 */
	private void downloadExcel(HSSFWorkbook workbook, String filename,
			HttpServletResponse response) {

		ServletOutputStream out = null;
		try {
			out = response.getOutputStream();
			response.setHeader("Content-Type", "application/force-download");
			response.setHeader("Content-Disposition", "attachment;filename="
					+ URLEncoder.encode(filename, "UTF-8"));
			workbook.write(out);
			out.close();
		} catch (Exception e) {
			logger.error(">>>>>fail to write output stream", e);
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					logger.error(">>>>>fail to close output stream", e);
				}
			}
		}
	}

	private String getNullString(Object data) {
		if (data == null) {
			return "";
		}
		String dataStr = String.valueOf(data);
		if ("null".equalsIgnoreCase(dataStr)) {
			return "";
		}
		return dataStr;
	}

//	/**
//	 * 返回错误响应消息
//	 * 
//	 * @param result
//	 * @param errMsg
//	 * @return
//	 */
//
//	private ResponseEntity<String> returnErrorResponse(
//			Map<String, Object> result, String errMsg) {
//		result.put("failure", Boolean.valueOf(true));
//		result.put("msg", errMsg);
//		return new ResponseEntity<String>(Json.toJson(result),
//				getHttpHeaders(), HttpStatus.OK);
//	}
//
//	/**
//	 * 返回成功响应消息
//	 * 
//	 * @param result
//	 * @param errMsg
//	 * @return
//	 */
//
//	private ResponseEntity<String> returnSuccessResponse(
//			Map<String, Object> result, String errMsg) {
//		result.put("success", Boolean.valueOf(true));
//		result.put("msg", errMsg);
//		return new ResponseEntity<String>(Json.toJson(result),
//				getHttpHeaders(), HttpStatus.OK);
//	}
//
//	/**
//	 * 获取http消息头
//	 * 
//	 * @return
//	 */
//	private HttpHeaders getHttpHeaders() {
//
//		HttpHeaders httpHeaders = new HttpHeaders();
//		MediaType mediaType = new MediaType("text", "html",
//				Charset.forName("utf-8"));
//		httpHeaders.setContentType(mediaType);
//		return httpHeaders;
//
//	}

}
